<template>
  <div class="cesiumContainer" ref="cesiumContainer"></div>
</template>

<script setup>
import * as Cesium from "cesium";
import { onMounted, ref, reactive, getCurrentInstance } from "vue";
import GUI from "lil-gui";

const cesiumContainer = ref(null);
let model = reactive({});
let scene = reactive({});
let viewer = reactive({});
let polylines = reactive({});
const operation = {
  value: "",
  selectOptions: {
    "基本添加": "addBillboard",
    "详细添加": "setBillboardProperties",
    "改变属性": "changeBillboardPropertes",
    "以米为单位添加": "sizeBillboardInMeters",
    "同时添加多个": "addMultipleBillboards",
    "远近时图的大小阈值": "scaleByDistance",
    "远近时淡入淡出阈值": "fadeByDistance",
    "同一点时进行偏移阈值": "offsetByDistance",
    "添加canvas类型广告牌": "addPointBillboards",
    "将图片绘制在指定的区域": "addMarkerBillboards",
    "更具新的坐标绘制": "inReferenceFrame",
  },
};
let currentInstance = getCurrentInstance();
let gui = new GUI();
gui
  .add(operation, "value", operation.selectOptions)
  .name("加载广告牌")
  .onChange((e) => {
    console.log("广告牌", currentInstance);
    scene.primitives.removeAll();
  });

// 相当于密钥，申请使用下边链接中的数据时需要用到
Cesium.Ion.defaultAccessToken =
  "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIyOTQ0YTExZS02N2Y4LTQ2OTMtOWQ4NS1mNzE3ZWMwYTNmNmEiLCJpZCI6NDM1OCwiaWF0IjoxNjI4MTQzMjE1fQ.csECCT352LHVhak2sJlWYXw_gr7U-AqdQ9UMvtfOeg8";

class Polylines {
  scene = null;
  constructor(scene) { 
    this.scene = scene;
  }

  /**
   * 创建并添加一个发光的多边线到场景中。
   * 该函数不接受参数并且没有返回值。
   */
  glowPolyline() {
    this.scene.primitives.add(new Cesium.Primitive({
      // 创建一个几何实例，用来表示多边线的形状和位置
      geometryInstances: new Cesium.GeometryInstance({
        geometry: new Cesium.PolylineGeometry({
          // 定义多边线的坐标位置（以度为单位）
          positions: Cesium.Cartesian3.fromDegreesArray([110, 40, 119, 40]),
          width: 10, // 多边线的宽度
          vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT, // 定义多边线的顶点格式
        }),
      }),
      // 创建一个外观，用来定义多边线的材质和渲染效果
      appearance: new Cesium.PolylineMaterialAppearance({
        material: Cesium.Material.fromType(Cesium.Material.PolylineGlowType), // 使用发光材质
      }),
    }));
  }

  /**
   * 添加带箭头的多边线到场景中。
   * 该函数不接受参数并且没有返回值。
   */
  polylineArrow() {
    this.scene.primitives.add(new Cesium.Primitive({
      geometryInstances: new Cesium.GeometryInstance({
        geometry: new Cesium.PolylineGeometry({
          // 定义多边线的地理位置，使用度数表示
          positions: Cesium.Cartesian3.fromDegreesArray([110, 39, 119, 39]),
          width: 10, // 定义多边线的宽度
          vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT, // 定义多边线的顶点格式
        }),
      }),
      appearance: new Cesium.PolylineMaterialAppearance({
        // 使用箭头材质为多边线着色
        material: Cesium.Material.fromType(Cesium.Material.PolylineArrowType),
      }),
    }));
  }

  /**
   * 添加一个折线轮廓到场景中。
   * 该函数不接受参数并且没有返回值。
   */
  polylineOutline() {
    this.scene.primitives.add(new Cesium.Primitive({
      // 创建一个几何实例来表示折线
      geometryInstances: new Cesium.GeometryInstance({
        geometry: new Cesium.PolylineGeometry({
          // 定义折线的位置，使用经纬度数组
          positions: Cesium.Cartesian3.fromDegreesArray([110, 38, 119, 38]),
          // 定义折线的宽度
          width: 10,
          // 定义折线的顶点格式
          vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT,
        }),
      }),
      // 使用材质外观来设置折线的样式
      appearance: new Cesium.PolylineMaterialAppearance({
        material: Cesium.Material.fromType(Cesium.Material.PolylineOutlineType),
      }),
    }));
  }


//  lineMaterial = new Cesium.PolylineArrowMaterialProperty({
//     color: Cesium.Color.RED, // 线的颜色
//     arrowSize: 0.5 // 箭头大小
// });
  polylineDashArrow() {
    this.scene.primitives.add(new Cesium.Primitive({
      geometryInstances:new Cesium.GeometryInstance({
        geometry: new Cesium.PolylineGeometry({
          // 定义多边线的地理位置，使用度数表示
          positions: Cesium.Cartesian3.fromDegreesArray([110, 37, 119, 37]),
          width: 10, // 定义多边线的宽度
          vertexFormat: Cesium.PolylineMaterialAppearance.VERTEX_FORMAT, // 定义多边线的顶点格式
        }),
      }), 
      appearance: new Cesium.PolylineMaterialAppearance({
        // 使用箭头材质为多边线着色
        material: Cesium.Material.fromType(Cesium.Material.PolylineDashType),
      }),
    }));  
    const canvas = document.createElement("canvas");
    canvas.width = 36;
    canvas.height = 36;
    const context2D = canvas.getContext("2d");
    context2D.beginPath();
    context2D.arc(10, 10, 10, 0, Cesium.Math.TWO_PI, true);
    // context2D.fillRect(10,10,20,20);
    // context2D.fillText("马维超", 10, 10);
    context2D.closePath();
    context2D.fillStyle = "rgb(255,255,255)";
    context2D.fill();
    const billboards = scene.primitives.add(new Cesium.BillboardCollection());
    billboards.add({
      image: canvas,
      imageId: "自定义点",
      position: Cesium.Cartesian3.fromDegrees(119, 37),
      color: new Cesium.Color(255, 255, 255, 1),
      scale: 0.5,
    }); 
  }
 

  
}

onMounted(async () => {
  viewer = new Cesium.Viewer(cesiumContainer.value, {
    baseLayerPicker: false, // 如果设置为false，将不会创建右上角图层按钮。
    fullscreenButton: false, // 如果设置为false，将不会创建右下角全屏按钮。
    vrButton: false, // 如果设置为false，将不会创建VR应用场景
    geocoder: false, // 如果设置为false，将不会创建右上角查询(放大镜)按钮。
    homeButton: false, // 如果设置为false，将不会创建右上角主页(房子)按钮。
    infoBox: false, // 是否显示点击要素之后显示的信息,cesium中的沙盒开关
    sceneModePicker: false, // 如果设置为false，将不会创建右上角投影方式控件(显示二三维切换按钮)。
    selectionIndicator: false, // 获取当选定实体更改时引发的事件。
    navigationHelpButton: false, // 如果设置为false，则不会创建右上角帮助(问号)按钮。
    navigationInstructionsInitiallyVisible: false, // 如果帮助说明最初应该是可见的，则为true；如果直到用户明确单击该按钮，则不显示该说明，否则为false。
    timeline: true, // 如果设置为false，则不会创建正下方时间轴小部件。
    scene3DOnly: true, // 为 true 时，每个几何实例将仅以3D渲染以节省GPU内存。
    animation: true, // 如果设置为false，将不会创建左下角动画小部件。
    shouldAnimate: false, // 默认true ，否则为 false 。此选项优先于设置 Viewer＃clockViewModel 。
    // ps. Viewer＃clockViewModel 是用于控制当前时间的时钟视图模型。我们这里用不到时钟，就把shouldAnimate设为false
    sceneMode: 3, // 初始场景模式 1 2D模式 2 2D循环模式 3 3D模式  Cesium.SceneMode
    requestRenderMode: false, // 启用请求渲染模式，不需要渲染，节约资源吧
    fullscreenElement: document.body, // 全屏时渲染的HTML元素 暂时没发现用处，虽然我关闭了全屏按钮，但是键盘按F11 浏览器也还是会进入全屏
    shadows: true,
  });

  //获取场景对象
  scene = viewer.scene;

  polylines = new Polylines(scene);
  polylines.glowPolyline();
  polylines.polylineArrow();
  polylines.polylineOutline();
  polylines.polylineDashArrow();

 
//   var line = viewer.entities.add({
//     polyline: {
//         positions: Cesium.Cartesian3.fromDegreesArray([
//             116.46, 39.92,
//             118.46, 40.92
//         ]),
//         width: 5, // 线宽
//         material: new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED), // 线材料，设置为箭头材料，并指定颜色
//         clampToGround: true // 是否贴地
//     }
// });

// 创建一个线条实体
var line = viewer.entities.add({
    polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray([
            119.4033203125,35.92806079705575,
            119.40577392578125,39.92796452521424
        ]),
        width: 5, // 线宽
        material: new Cesium.PolylineDashMaterialProperty({
            color: Cesium.Color.RED,
            gapColor: Cesium.Color.TRANSPARENT,
            dashLength: 10.0, // 虚线每段长度
            dashPattern: 255 // 虚线样式
        }),
        arcType: Cesium.ArcType.RHUMB
    }
});
 
// 添加箭头
line.polyline.material = new Cesium.PolylineArrowMaterialProperty(Cesium.Color.RED);
 


  scene.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(119, 40, 1000000),
    orientation: {
      heading: Cesium.Math.toRadians(0),
      pitch: Cesium.Math.toRadians(-90),
      roll: 0,
    },
  });
 

  const handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
  handler.setInputAction((e) => {
    const pick = scene.pick(e.endPosition);
    if (
      Cesium.defined(pick) &&
      Cesium.defined(pick.node) &&
      Cesium.defined(pick.mesh)
    ) {
      console.log(`node:${pick.node.name},mesh:${pick.mesh.name}`);
    }
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
});
</script> 
<style scoped>
.cesiumContainer {
  width: 100%;
  height: 100vh;
}
</style>
